using System;
using System.IO;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using MarkdownRow.Assets;
using MarkdownRow.EditView;
using MarkdownRow.Views;
using Newtonsoft.Json;

namespace MarkdownRow;

public partial class MainWindow : Window
{
    public Doc Doc { get; }
    public Setting Setting { get; }
    private string FilePath { get; set; }

    public MainWindow(Doc doc, Setting? setting, string? path = "")
    {
        InitializeComponent();
        Doc = doc;
        Setting = setting ?? new Setting();
        Control.Content = new Home(setting!.UseFiles);
        FilePath = path ?? "";
        if (File.Exists(path))
            ToView(path);
    }

    public async void Save()
    {
        if (Control.Content is not Editor editor) return;
        var text = editor.GetText();
        if (!File.Exists(FilePath))
        {
            var result = await StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
            {
                Title = "Choose the Markdown file", FileTypeChoices = new[]
                {
                    new FilePickerFileType("All Markdown File")
                    {
                        Patterns = new[] { "*.md", "*.markdown" },
                    },
                    new FilePickerFileType("All File")
                    {
                        Patterns = new[] { "*.*" }
                    }
                }
            });
            if (result == null) return;
            await using var stream = await result.OpenWriteAsync();
            await using var writer = new StreamWriter(stream);
            await writer.WriteAsync(text);
            return;
        }

        await File.WriteAllTextAsync(FilePath, text);
    }

    public void ToCreateView()
    {
        if(Setting.EditorType == "Simple")
            Control.Content = new SimpleEditor("");
        else 
            Control.Content = new EvenRenderingEditor("");
        Title = "新文件";
        FilePath = "";
    }

    public void ToView(string path)
    {
        FilePath = path;
        Title = Path.GetFileName(path);
        var s = File.ReadAllText(path);
        if(Setting.EditorType == "Simple")
            Control.Content = new SimpleEditor(s);
        else 
            Control.Content = new EvenRenderingEditor(s);
    }

    public async void Open()
    {
        var result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions()
        {
            AllowMultiple = false, Title = "Choose the Markdown file", FileTypeFilter = new[]
            {
                new FilePickerFileType("All Markdown File")
                {
                    Patterns = new[] { "*.md", "*.markdown" }
                },
                new FilePickerFileType("All File")
                {
                    Patterns = new[] { "*.*" }
                }
            }
        });
        var file = result.FirstOrDefault();
        if (file == null) return;
        FilePath = file.Path.LocalPath;
        await using var context = await file.OpenReadAsync();

        using var stream = new StreamReader(context);
        var s = await stream.ReadToEndAsync();

        var tt = Type.GetType($"MarkdownRow.EditView.{Setting.EditorType}Editor");
        if (Control.Content is Editor editor)
            editor.ContextChange(s);
        else
            Control.Content = Activator.CreateInstance(tt!, s);
    }

    private void CopyMenuClick(object? sender, RoutedEventArgs e)
    {
        if (Control.Content is not Editor editor) return;
        editor.CopyMenuClick(sender, e);
    }

    private void PasteMenuClick(object? sender, RoutedEventArgs e)
    {
        if (Control.Content is not Editor editor) return;
        editor.PasteMenuClick(sender, e);
    }

    private void ShowTabs(object? sender, RoutedEventArgs e)
    {
        if (Control.Content is not Editor editor) return;
        editor.ShowTabs(sender, e);
    }

    private void ShowSpaces(object? sender, RoutedEventArgs e)
    {
        if (Control.Content is not Editor editor) return;
        editor.ShowSpaces(sender, e);
    }

    private void ShowEOL(object? sender, RoutedEventArgs e)
    {
        if (Control.Content is not Editor editor) return;
        editor.ShowEOL(sender, e);
    }

    private void SearchMenuClick(object? sender, RoutedEventArgs e)
    {
        if (Control.Content is not Editor editor) return;
        editor.SearchMenuClick(sender, e);
    }

    private void CutMenuClick(object? sender, RoutedEventArgs e)
    {
        if (Control.Content is not Editor editor) return;
        editor.CutMenuClick(sender, e);
    }

    protected override void OnClosed(EventArgs e)
    {
        if (string.IsNullOrEmpty(FilePath)) return;
        var index = Setting.UseFiles.FindIndex(x => x.FilePath == FilePath);
        if (index > -1 && index < Setting.UseFiles.Count)
            Setting.UseFiles[index] = new UseFile() { FilePath = FilePath, Time = DateTime.Today.ToString("D") };
        else Setting.UseFiles.Add(new UseFile() { FilePath = FilePath, Time = DateTime.Today.ToString("D") });
        
        File.WriteAllText("setting.json",JsonConvert.SerializeObject(Setting));
        
        base.OnClosed(e);
    }

    private void HelperClick(object? sender, RoutedEventArgs e)
    {
        var main = new MainWindow(Doc, Setting)
        {
            Control = { Content = new HelperView() }
        };
        main.Show();
    }
}